package approval

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"

	"github.com/fisker/zjump-backend/internal/model"
	"gorm.io/gorm"
)

// WeChatProvider 企业微信审批提供者
type WeChatProvider struct {
	config  *model.ApprovalConfig
	baseURL string
	client  *http.Client
	db      *gorm.DB
}

// NewWeChatProvider 创建企业微信审批提供者
func NewWeChatProvider(config *model.ApprovalConfig, db *gorm.DB) *WeChatProvider {
	// 使用用户配置的API基础URL，如果没有配置则使用默认值
	baseURL := config.APIBaseURL
	if baseURL == "" {
		baseURL = "https://qyapi.weixin.qq.com" // 默认值
	}

	return &WeChatProvider{
		config:  config,
		baseURL: baseURL,
		client: &http.Client{
			Timeout: 30 * time.Second,
		},
		db: db,
	}
}

// CreateApproval 创建企业微信审批
func (p *WeChatProvider) CreateApproval(ctx context.Context, approval *model.Approval) (string, error) {
	// 检查审批代码是否存在
	if p.config.TemplateID == "" {
		return "", fmt.Errorf("审批代码未配置")
	}

	// 获取访问令牌
	token, err := p.getAccessToken(ctx)
	if err != nil {
		return "", fmt.Errorf("获取访问令牌失败: %v", err)
	}

	// 构建审批表单
	formContent := p.buildFormContent(approval)

	// 创建审批实例
	return p.createApprovalInstance(ctx, token, formContent, approval)
}

// getAccessToken 获取企业微信访问令牌
func (p *WeChatProvider) getAccessToken(ctx context.Context) (string, error) {
	url := fmt.Sprintf("%s/cgi-bin/gettoken?corpid=%s&corpsecret=%s", p.baseURL, p.config.AppID, p.config.AppSecret)

	req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
	if err != nil {
		return "", err
	}

	resp, err := p.client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	var result struct {
		ErrCode int    `json:"errcode"`
		ErrMsg  string `json:"errmsg"`
		Token   string `json:"access_token"`
	}

	if err := json.Unmarshal(body, &result); err != nil {
		return "", fmt.Errorf("解析响应失败: %v", err)
	}

	if result.ErrCode != 0 {
		return "", fmt.Errorf("企业微信API错误 [%d]: %s", result.ErrCode, result.ErrMsg)
	}

	return result.Token, nil
}

// buildFormContent 构建表单内容
func (p *WeChatProvider) buildFormContent(approval *model.Approval) string {
	formData := []map[string]interface{}{
		{
			"title": "工单标题",
			"value": approval.Title,
		},
		{
			"title": "详细描述",
			"value": approval.Description,
		},
		{
			"title": "申请理由",
			"value": approval.Reason,
		},
		{
			"title": "申请资源",
			"value": fmt.Sprintf("%v", approval.ResourceNames),
		},
		{
			"title": "权限时长",
			"value": fmt.Sprintf("%d小时", approval.Duration),
		},
	}

	jsonData, _ := json.Marshal(formData)
	return string(jsonData)
}

// createApprovalInstance 创建审批实例
func (p *WeChatProvider) createApprovalInstance(ctx context.Context, token, formContent string, approval *model.Approval) (string, error) {
	// 使用数据库配置中的API路径，如果没有配置则使用默认路径
	apiPath := p.config.APIPath
	if apiPath == "" {
		apiPath = "/cgi-bin/oa/applyevent" // 默认路径
	}
	url := fmt.Sprintf("%s%s?access_token=%s", p.baseURL, apiPath, token)

	// 直接使用当前登录用户的用户名作为userID
	userID := approval.ApplicantID
	if userID == "" {
		userID = approval.ApplicantName // 如果ApplicantID为空，使用ApplicantName
	}

	// 从配置中读取审批人列表
	var approverIDs []string
	if p.config.ApproverUserIDs != "" {
		json.Unmarshal([]byte(p.config.ApproverUserIDs), &approverIDs)
	}

	// 构建审批人列表
	approverList := []map[string]interface{}{}
	if len(approverIDs) > 0 {
		for _, approverID := range approverIDs {
			approverList = append(approverList, map[string]interface{}{
				"userid": approverID,
			})
		}
	} else {
		// 如果没有配置审批人，使用申请人作为审批人
		approverList = append(approverList, map[string]interface{}{
			"userid": userID,
		})
	}

	reqBody := map[string]interface{}{
		"creator_userid":        userID,
		"template_id":           p.config.TemplateID,
		"use_template_approver": 0, // 不使用模板审批人，使用自定义审批人
		"approver":              approverList,
		"form_data":             json.RawMessage(formContent),
	}

	body, _ := json.Marshal(reqBody)
	req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(body))
	if err != nil {
		return "", err
	}

	req.Header.Set("Content-Type", "application/json")

	resp, err := p.client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	var result struct {
		ErrCode int    `json:"errcode"`
		ErrMsg  string `json:"errmsg"`
		SpNo    string `json:"sp_no"`
	}

	if err := json.Unmarshal(respBody, &result); err != nil {
		return "", fmt.Errorf("解析响应失败: %v", err)
	}

	if result.ErrCode != 0 {
		return "", fmt.Errorf("企业微信API错误 [%d]: %s", result.ErrCode, result.ErrMsg)
	}

	return result.SpNo, nil
}

// GetName 获取平台名称
func (p *WeChatProvider) GetName() string {
	return "企业微信"
}

// GetApprovalStatus 获取审批状态
func (p *WeChatProvider) GetApprovalStatus(ctx context.Context, externalID string) (*ApprovalStatusResponse, error) {
	// 获取访问令牌
	token, err := p.getAccessToken(ctx)
	if err != nil {
		return nil, fmt.Errorf("获取访问令牌失败: %v", err)
	}

	// 查询审批实例详情
	// 使用数据库配置中的API路径，如果没有配置则使用默认路径
	apiPathGet := p.config.APIPathGet
	if apiPathGet == "" {
		apiPathGet = "/cgi-bin/oa/getapprovaldetail" // 默认路径
	}
	url := fmt.Sprintf("%s%s?access_token=%s", p.baseURL, apiPathGet, token)

	reqBody := map[string]interface{}{
		"sp_no": externalID,
	}

	body, _ := json.Marshal(reqBody)
	req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(body))
	if err != nil {
		return nil, err
	}

	req.Header.Set("Content-Type", "application/json")

	resp, err := p.client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	var result struct {
		ErrCode int    `json:"errcode"`
		ErrMsg  string `json:"errmsg"`
		Info    struct {
			Status   string `json:"status"`
			SpStatus string `json:"sp_status"`
		} `json:"info"`
	}

	if err := json.Unmarshal(respBody, &result); err != nil {
		return nil, fmt.Errorf("解析响应失败: %v", err)
	}

	if result.ErrCode != 0 {
		return nil, fmt.Errorf("企业微信API错误 [%d]: %s", result.ErrCode, result.ErrMsg)
	}

	// 映射状态
	status := p.mapStatus(result.Info.SpStatus)

	return &ApprovalStatusResponse{
		Status: status,
	}, nil
}

// CancelApproval 取消审批
func (p *WeChatProvider) CancelApproval(ctx context.Context, externalID string) error {
	// 获取访问令牌
	token, err := p.getAccessToken(ctx)
	if err != nil {
		return fmt.Errorf("获取访问令牌失败: %v", err)
	}

	// 取消审批实例
	// 使用数据库配置中的API路径，如果没有配置则使用默认路径
	apiPathCancel := p.config.APIPathCancel
	if apiPathCancel == "" {
		apiPathCancel = "/cgi-bin/oa/applyevent/cancel" // 默认路径
	}
	url := fmt.Sprintf("%s%s?access_token=%s", p.baseURL, apiPathCancel, token)

	reqBody := map[string]interface{}{
		"sp_no":  externalID,
		"userid": p.config.AppID, // 使用应用ID作为操作人
	}

	body, _ := json.Marshal(reqBody)
	req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(body))
	if err != nil {
		return err
	}

	req.Header.Set("Content-Type", "application/json")

	resp, err := p.client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	var result struct {
		ErrCode int    `json:"errcode"`
		ErrMsg  string `json:"errmsg"`
	}

	if err := json.Unmarshal(respBody, &result); err != nil {
		return fmt.Errorf("解析响应失败: %v", err)
	}

	if result.ErrCode != 0 {
		return fmt.Errorf("企业微信API错误 [%d]: %s", result.ErrCode, result.ErrMsg)
	}

	return nil
}

// HandleCallback 处理回调
func (p *WeChatProvider) HandleCallback(ctx context.Context, data interface{}) (*CallbackResult, error) {
	// 企业微信回调处理逻辑
	return nil, fmt.Errorf("企业微信回调处理未实现")
}

// ValidateConfig 验证配置
func (p *WeChatProvider) ValidateConfig(config map[string]interface{}) error {
	// 验证企业微信配置
	return nil
}

// mapStatus 映射企业微信状态到系统状态
func (p *WeChatProvider) mapStatus(weChatStatus string) model.ApprovalStatus {
	switch weChatStatus {
	case "1": // 审批中
		return model.ApprovalStatusPending
	case "2": // 已通过
		return model.ApprovalStatusApproved
	case "3": // 已驳回
		return model.ApprovalStatusRejected
	case "4": // 已撤销
		return model.ApprovalStatusCanceled
	default:
		return model.ApprovalStatusPending
	}
}
